package com.enseirb.bdxmap.activity;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.enseirb.bdxmap.R;
import com.enseirb.bdxmap.activity.adapter.DataSourceAdapter;
import com.enseirb.bdxmap.activity.adapter.DataSourceItem;
import com.enseirb.bdxmap.activity.listener.MarkerListener;
import com.enseirb.bdxmap.activity.task.DefibrillatorTask;
import com.enseirb.bdxmap.activity.task.ParkingTask;
import com.enseirb.bdxmap.activity.task.RestroomTask;
import com.enseirb.bdxmap.activity.task.UserTask;
import com.enseirb.bdxmap.activity.task.WifiTask;
import com.enseirb.bdxmap.preferences.PreferencesManager;
import com.enseirb.bdxmap.preferences.SharedPreferencesManager;
import com.enseirb.bdxmap.service.UserMarkerService;
import com.enseirb.bdxmap.service.model.DefibrillatorMarkerBO;
import com.enseirb.bdxmap.service.model.ParkingMarkerBO;
import com.enseirb.bdxmap.service.model.RestroomMarkerBO;
import com.enseirb.bdxmap.service.model.UserMarkerBO;
import com.enseirb.bdxmap.service.model.WifiMarkerBO;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends Activity implements MarkerListener{

	/* Global */
	private PreferencesManager preferencesManager = new SharedPreferencesManager(this);
	public static String waitingMessage;

	/*constants*/
	public static final int DEFIBRILATOR	= 0;
	public static final int PARKING			= 1;
	public static final int RESTROOM		= 2;
	public static final int WIFI			= 3;

	/* Navigation drawer */
	private List<DataSourceItem> dataSource = new ArrayList<DataSourceItem>();
	private ListView dataSourceListView;
	private DrawerLayout dataSourceLayout;
	private CustomActionBarDrawerToggle actionBarDrawerToggle;

	/* Google map */
	private GoogleMap	map;
	private TextView	longitude;
	private TextView	latitude;
	private EditText	title;
	private EditText	description;

	private UserMarkerService userMarkerService = new UserMarkerService(this);

	/* Initializations */

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		
		this.initFields();
		this.initResources();
		this.initNavigationDrawer();
		try {
			this.initMap();
		} catch (GooglePlayServicesNotAvailableException e) {
			e.printStackTrace();
		}
		this.initListeners();
	}

	private void initFields() {
		this.dataSourceListView	= (ListView) findViewById(R.id.main_lv_data_source);
		this.dataSourceLayout	= (DrawerLayout) findViewById(R.id.main_drawer_layout);
	}

	private void initResources() {
		String[] names = getResources().getStringArray(R.array.data_source);
		Drawable[] drawables = {	getResources().getDrawable(R.drawable.defibrillateur_icon),
									getResources().getDrawable(R.drawable.parking_icon),
									getResources().getDrawable(R.drawable.wc_icon),
									getResources().getDrawable(R.drawable.wifi_icon)};

		for (int i = 0; i < names.length && i < drawables.length; ++i) {
			dataSource.add(new DataSourceItem(names[i], drawables[i]));
		}
		
		waitingMessage	= getResources().getString(R.string.waiting_mess);
	}

	private void initNavigationDrawer() {
		dataSourceListView.setAdapter(new DataSourceAdapter(this, dataSource));
		getActionBar().setDisplayHomeAsUpEnabled(true);
		getActionBar().setHomeButtonEnabled(true);
		actionBarDrawerToggle = new CustomActionBarDrawerToggle(this, dataSourceLayout);
		dataSourceLayout.setDrawerListener(actionBarDrawerToggle);
	}

	private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle {

		public CustomActionBarDrawerToggle(Activity activity, DrawerLayout layout){
			super(activity, layout, R.drawable.ic_drawer, R.string.menu_open, R.string.menu_close);
		}
	}

	private void initListeners() {
		this.initNavigationDrawerListener();
		this.initMapListener();
	}

	private void initNavigationDrawerListener() {
		dataSourceListView.setOnItemClickListener(new DrawerItemClickListener());
	}

	private void initMapListener() {
		map.setOnMarkerClickListener(new OnMarkerClickListener() {
			@Override
			public boolean onMarkerClick(Marker marker) {
				showInformations(marker);
				return true;
			}
		});   

		map.setOnMapLongClickListener(new OnMapLongClickListener() {

			@Override
			public void onMapLongClick(LatLng latLng) {
				Vibrator vb = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
				vb.vibrate(getResources().getInteger(R.integer.vibrate_level));
				showNewMarkerPopup(latLng);
			}
		});
	}

	private class DrawerItemClickListener implements ListView.OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			checkDataSourceClick(position);
		}
	}

	/* Map management */

	private void initMap() throws GooglePlayServicesNotAvailableException {
		MapsInitializer.initialize(getApplicationContext());
		
		map = ((MapFragment) getFragmentManager().findFragmentById(R.id.main_map_fragment)).getMap();
		if (map != null){
			map.setMyLocationEnabled(true);
			map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(Double.valueOf(getResources().getString(R.string.init_lat)), 
																		Double.valueOf(getResources().getString(R.string.init_lon))),
																		getResources().getInteger(R.integer.init_level_zoom)));
			checkDataSourceClick(preferencesManager.loadDataSourceChoice());
		}
	}

	private void showInformations(Marker marker) {
		AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
		alertDialog.setTitle(marker.getTitle());
		alertDialog.setMessage(marker.getSnippet());
		AlertDialog alert = alertDialog.create();
		alert.show();
	}

	private void showNewMarkerPopup(final LatLng latLng) {
		AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
		alertDialog.setTitle(getResources().getString(R.string.user_marker_title));
		alertDialog.setCancelable(false);

		LayoutInflater inflater = getLayoutInflater();
		View dialoglayout = inflater.inflate(R.layout.new_marker_layout, new LinearLayout(this), false);
		alertDialog.setView(dialoglayout);

		initNewMarkerPopup(latLng, dialoglayout);
		
		alertDialog.setPositiveButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				if (!title.getText().toString().isEmpty()) {
					UserMarkerBO userMarker = new UserMarkerBO();
					userMarker.latitude		= latLng.latitude;
					userMarker.longitude	= latLng.longitude;
					userMarker.name			= title.getText().toString();
					userMarker.description	= description.getText().toString();
					userMarkerService.addMarker(userMarker);
					printUserMarker(userMarker);
				} else {
					Toast.makeText(getApplicationContext(), getResources().getString(R.string.titleMissing), Toast.LENGTH_SHORT).show();
				}
			}
		});

		alertDialog.setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
			}
		});

		AlertDialog alert = alertDialog.create();
		alert.show();
	}

	private void initNewMarkerPopup(LatLng latLng, View dialoglayout) {
		this.longitude		= (TextView) dialoglayout.findViewById(R.id.longitude);
		this.latitude		= (TextView) dialoglayout.findViewById(R.id.latitude);
		this.title			= (EditText) dialoglayout.findViewById(R.id.title);
		this.description	= (EditText) dialoglayout.findViewById(R.id.description);
		this.longitude.setText(Float.valueOf(String.valueOf(latLng.longitude)).toString());
		this.latitude.setText(Float.valueOf(String.valueOf(latLng.latitude)).toString());
	}


	
	private void checkDataSourceClick(int position) {
		dataSourceLayout.closeDrawers();
		if(position >= 0 && position < dataSource.size()) {
			preferencesManager.saveDataSourceChoice(position);
			getActionBar().setTitle(dataSource.get(position).name);
			map.clear();
			
			// Print the user markers
			new UserTask(this).execute();
			
			// Print the chosen markers
			switch (position) {
				case DEFIBRILATOR:
					new DefibrillatorTask(this).execute();
					break;
				case PARKING:
					new ParkingTask(this).execute();
					break;
				case RESTROOM:
					new RestroomTask(this).execute();
					break;
				case WIFI:
					new WifiTask(this).execute();
					break;
				default:
					break;
			}
		}
	}

	@Override
	public void printDefibrillatorMarkers(List<DefibrillatorMarkerBO> markers) {
		for (DefibrillatorMarkerBO defibrillator : markers) {
			map.addMarker(new MarkerOptions()
								.position(new LatLng(defibrillator.latitude, defibrillator.longitude))
								.title(defibrillator.name)
								.snippet(	getResources().getString(R.string.defibrillator_type) +
											defibrillator.typology +
											getResources().getString(R.string.defibrillator_info) +
											defibrillator.information)
								.icon(BitmapDescriptorFactory.fromResource(R.drawable.defibrillateur_icon)));
		}
	}

	@Override
	public void printParkingMarkers(List<ParkingMarkerBO> markers) {
		for (ParkingMarkerBO parking : markers) {
			map.addMarker(new MarkerOptions()
								.position(new LatLng(parking.latitude, parking.longitude))
								.title(parking.name)
								.snippet(	getResources().getString(R.string.parking_type) +
											parking.type +
											getResources().getString(R.string.parking_spots) +
											parking.nbSpots)
								.icon(BitmapDescriptorFactory.fromResource(R.drawable.parking_icon)));
		}
	}

	@Override
	public void printRestroomMarkers(List<RestroomMarkerBO> markers) {
		for (RestroomMarkerBO restroom : markers) {
			map.addMarker(new MarkerOptions()
								.position(new LatLng(restroom.latitude, restroom.longitude))
								.title(restroom.name)
								.snippet(	getResources().getString(R.string.restroom_type) +
											restroom.typology +
											getResources().getString(R.string.restroom_options) +
											restroom.options)
								.icon(BitmapDescriptorFactory.fromResource(R.drawable.wp_icon)));
		}
	}

	@Override
	public void printWifiMarkers(List<WifiMarkerBO> markers) {
		for (WifiMarkerBO wifi : markers) {
			map.addMarker(new MarkerOptions()
								.position(new LatLng(wifi.latitude, wifi.longitude))
								.title(wifi.name)
								.snippet(	getResources().getString(R.string.wifi_key) +
											wifi.key +
											getResources().getString(R.string.wifi_area)+
											wifi.area)
								.icon(BitmapDescriptorFactory.fromResource(R.drawable.wifi_icon)));
		}
	}
	
	@Override
	public void printUserMarkers(List<UserMarkerBO> markers) {
		for (UserMarkerBO marker : markers) {
			printUserMarker(marker);
		}
	}

	private void printUserMarker(UserMarkerBO marker) {
		map.addMarker(new MarkerOptions()
							.position(new LatLng(marker.latitude, marker.longitude))
							.title(marker.name)
							.snippet(marker.description)
							.icon(BitmapDescriptorFactory.fromResource(R.drawable.perso_icon)));
	}

	/* Option menu */

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_about) {
			showAlertDialog(getResources().getString(R.string.action_about), getResources().getString(R.string.about_text));
		}
		if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		actionBarDrawerToggle.syncState();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		actionBarDrawerToggle.onConfigurationChanged(newConfig);
	}

	@Override
	public void printError(String message) {
		showAlertDialog(getResources().getString(R.string.error), message);
	}
	
	private void showAlertDialog(String title, String message) {
		AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
		alertDialog.setTitle(title);
		alertDialog.setMessage(message);
		AlertDialog alert = alertDialog.create();
		alert.show();
	}
}
